package com.mine.androidlearn.common.base;

import android.content.Context;
import android.util.Log;

import com.mine.androidlearn.api.ApiWrapper;
import com.mine.androidlearn.api.exception.ApiException;
import com.mine.androidlearn.api.exception.NetworkNotConnectedException;
import com.mine.androidlearn.common.db.DbUtil;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.ref.Reference;
import java.lang.ref.WeakReference;
import java.net.ConnectException;
import java.net.SocketTimeoutException;

import rx.Subscriber;
import rx.Subscription;
import rx.functions.Action1;
import rx.subscriptions.CompositeSubscription;

/**
 * Presenter的基类
 * 
 * @author mine
 * @version V1.0 2018/8/5 15:56
 */
public abstract class BasePresenter<T extends IBaseView> {

    private static final String TAG = BasePresenter.class.getSimpleName();
    private static Logger sLogger = LoggerFactory.getLogger(TAG);

    protected final ApiWrapper mApi; // api
    private WeakReference<T> mViewWeakRef; // view
    private Context mContext; // 上下文
    public CompositeSubscription mSubscriptions; //用来保存所有的Subscriptions

    public BasePresenter(Context context) {
        this.mContext = context;
        mApi = ApiWrapper.getInstance(context);
    }

    /**
     * 获取上下文
     */
    public Context getContext() {
        return mContext;
    }

    /**
     * 建立关联
     *
     * @param view view
     */
    protected void attachView(T view) {
        mViewWeakRef = new WeakReference<>(view);
        this.mSubscriptions = new CompositeSubscription();
    }

    /**
     * 获取view
     *
     * @return view
     */
    protected T getView() {
        if (mViewWeakRef != null) {
            return mViewWeakRef.get();
        }
        return null;
    }

    /**
     * 解除关联
     */
    protected void detachView() {
        if (mViewWeakRef != null) {
            mViewWeakRef.clear();
            mViewWeakRef = null;
        }
    }

    /**
     * Add Subscription
     *
     * @param sub
     */
    protected void addSubscription(Subscription sub) {
        mSubscriptions.add(sub);
    }

    /**
     * isUnsubscribed
     *
     * @return
     */
    protected boolean isUnsubscribed() {
        return mSubscriptions.isUnsubscribed();
    }

    /**
     * Unsubscribe
     */
    protected void unsubscribe() {
        mSubscriptions.unsubscribe();
    }

    /**
     * Create Subscriber
     *
     * @param onNext
     * @param isSilent 是否静默，如果设置为静默（true），则api异常信息将不显示于界面
     * @param <T>
     * @return
     */
    protected <T> Subscriber newSubscriber(final Action1<? super T> onNext, final IBaseView view, final boolean
            isSilent) {
        return new Subscriber<T>() {
            @Override
            public void onCompleted() {
                /**
                 * 会导致再次发起网络请求时候loading圈被提前消失掉
                 */
//                view.hideLoading();
            }

            @Override
            public void onError(Throwable e) {
                view.hideLoading();
                if (!isSilent) {
                    showException(view, e);
                }
                sLogger.error(e.getMessage());
            }

            @Override
            public void onNext(T t) {
                view.hideLoading();
                if (!isUnsubscribed()) {
                    onNext.call(t);
                }
            }
        };
    }

    /**
     * 显示异常提示信息
     *
     * @param view
     * @param e
     */
    protected void showException(IBaseView view, Throwable e) {
        if (e instanceof ApiException) {
            view.showApiError(((ApiException) e).getApiExceptionMessage());
//        } else if (e instanceof SocketTimeoutException
//                || e instanceof ConnectException) {
//            view.showServerOrNetworkError();
        } else if (e instanceof NetworkNotConnectedException) {
            view.showNetworkNotConnected();
        } else {
//            view.showApiError(e.getMessage());
            view.showServerOrNetworkError();
        }
    }
}
